//
// Created by LiuYou on 2021/10/21.
//

#include <iostream>
#include <unistd.h>

/*
NAME
   execl, execlp, execle, execv, execvp, execvpe - execute a file
   这几个函数都是执行一个可执行的二进制文件。

SYNOPSIS
    #include <unistd.h>

    extern char** environ;

    // 这个是需要一个可执行文件完整的路径。
    // 但是要注意: todo 笔记: 第二个参数 arg 是从下标 0, 开始的！所以第一个参数一定是可执行文件名。
    int execl(const char *pathname, const char *arg, ...
                   / * (char  *) NULL * /);

    // 可以只给一个可执行文件的名字, 它会去环境变量中找。
    int execlp(const char* file, const char* arg, ...
            / * (char  *) NULL * /);

    int execle(const char* pathname, const char* arg, ...
            / *, (char *) NULL, char *const envp[] * /);

    int execv(const char* pathname, char* const argv[]);

    int execvp(const char* file, char* const argv[]);

    int execvpe(const char* file, char* const argv[],
                char* const envp[]);

DESCRIPTION
    The  exec()  family of functions replaces the current process image with a new process image.  The functions described in this manual page are
    frontends for execve(2).  (See the manual page for execve(2) for further details about the replacement of the current process image.)
    exec() 系列函数用新的进程映像(进程的虚拟空间) 替换 当前进程映像(进程的虚拟空间)。
    本手册页中描述的函数是 execve(2) 的前端。 （有关替换当前进程映像的更多详细信息，请参阅 execve(2) 的手册页。）

    The initial argument for these functions is the name of a file that is to be executed.
    这些函数的初始化参数是要执行的文件的名称。

    The functions can be grouped based on the letters following the "exec" prefix.
    可以根据“exec”前缀后面的字母对函数进行分组。

*/


/**
 * @brief 打印时间戳。
 * @details $ date +%s
 * @param argc
 * @param argv
 * @return
 */
int main(int argc, char** argv) {
    /*
     * todo 笔记: 在 exec函数族的使用中, 也必须使用 fflush(nullptr); 来刷新所有成功打开的流。
     */
    puts( "Begin!" );

    fflush( nullptr );

    // todo 笔记: execl(); 这个函数必须要指定可执行文件的绝对路径！
//    execl( "/usr/bin/date", "date", "+%s", nullptr );
    //  todo 笔记: 如果只是可执行文件名的话, 报错为: execl(): No such file or directory
    //   所以 execl();函数必须指定可执行文件的绝对路径！
//    execl( "date", "date", nullptr );


    // todo 笔记: execlp(); 这个函数会去环境变量中找这个可执行文件。
    execlp( "date", "date", nullptr );


    perror( "execl()" );
    exit( 1 );

    puts( "End!" );



    //<editor-fold desc="小例子">
//    fflush( nullptr );
//    pid_t childPid = fork();
//    if (childPid < 0) {
//        perror( "fork()" );
//        exit( 1 );
//    }
//
//    if (childPid == 0) {
//        execl( "/usr/bin/date", "date", "+%s", nullptr );
//        perror( "execl()" );
//        exit( 1 );
//    }
    //</editor-fold>

    return 0;
}
